import React from "react";
import { Clef, Note, NoteSymbol, staffTable } from "../../service/staff";
import { Blackboard } from '../blackboard/Blackboard';
import { Keyboard } from '../keyboard/Keyboard';
import * as Tone from 'tone'


export class PianoGamer {

    // store the note symbol of current round
    private noteSymbol: NoteSymbol;

    // e.g C4 is from 4th group
    private currentGroup: number;

    private correctNumber = 0;

    private errorNumber = 0;

    private synth = new Tone.Synth().toDestination();

    public nextRound(): { noteSymbol: NoteSymbol; clef: Clef } {

        // random generate note

        // we do not want two same note
        let nextNote = staffTable[Math.floor(Math.random() * staffTable.length)];
        while (nextNote.note === this.noteSymbol?.note) {
            nextNote = staffTable[Math.floor(Math.random() * staffTable.length)];
        }

        this.noteSymbol = nextNote;

        this.currentGroup = Number(this.noteSymbol.note.slice(-1))

        return {
            noteSymbol: this.noteSymbol,
            clef: 'G'
        };
    }

    public play(note: Note): { correct: number; error: number } {

        const clickedNote = note + this.currentGroup;
        //play a note for the duration of an 8th note
        this.synth.triggerAttackRelease(clickedNote, "8n");

        if (clickedNote === this.noteSymbol.note) {
            this.correctNumber = this.correctNumber + 1;
        } else {
            this.errorNumber = this.errorNumber + 1;
        }

        return {
            correct: this.correctNumber,
            error: this.errorNumber
        };
    }
}

const pianoGamer = new PianoGamer();


interface PianoState {

    noteSymbol?: NoteSymbol;

    clef?: Clef;

    correctNumber?: number;

    errorNumber?: number;
}

export class Piano extends React.Component<{}, PianoState> {

    state: Readonly<PianoState> = {}

    onClick = (note: Note) => {
        const score = pianoGamer.play(note);

        const question = pianoGamer.nextRound();

        this.setState({
            correctNumber: score.correct,
            errorNumber: score.error,
            noteSymbol: question.noteSymbol,
            clef: question.clef
        });
    }

    componentDidMount = () => {
        const question = pianoGamer.nextRound();
        this.setState({
            correctNumber: 0,
            errorNumber: 0,
            noteSymbol: question.noteSymbol,
            clef: question.clef
        });
    }

    render = () => {

        return <>
            <Blackboard noteSymbol={this.state.noteSymbol} clef={this.state.clef} correctNumber={this.state.correctNumber} errorNumber={this.state.errorNumber}></Blackboard>
            <Keyboard onClick={this.onClick}></Keyboard>
        </>
    }

}